﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using DomainDriver.DomainModeling.DataProviders;

namespace DomainDriver.DomainModeling.Queries
{
    public class LinqParameterizedQuery<T> : IParameterizedQuery<T>
    {
        private IDataProvider m_DataProvider;
        private Expression<Func<T, object, bool>> m_QueryExpression;
        private string m_ParameterName;
        private object m_DesiredParameterValue;

        public LinqParameterizedQuery(Expression<Func<T, object, bool>> queryExpression, string parameterName, object desiredParameterValue)
        {
            if (parameterName == null)
            { throw new ApplicationException(); }

            m_ParameterName = parameterName;
            m_DesiredParameterValue = desiredParameterValue;
            m_QueryExpression = queryExpression;
        }

        public IList<string> Parameters
        {
            get
            {
                List<string> parameters = new List<string>();
                parameters.Add(m_ParameterName);
                return parameters;
            }
        }

        public IDictionary<string, object> ParameterValues
        {
            get
            {
                Dictionary<string, object> parameterValues = new Dictionary<string, object>();
                parameterValues.Add(m_ParameterName, m_DesiredParameterValue);
                return parameterValues;
            }
        }

        public void SetQueryParameter(string parameterName, object value)
        {
            if (!m_ParameterName.Equals(parameterName))
            { throw new ApplicationException(); }

            m_DesiredParameterValue = value;
        }

        public Func<T, bool> GetQueryPredicate(IDataProvider dataProvider)
        {
            m_DataProvider = dataProvider;
            Func<T, bool> wrapperPredicate = new Func<T, bool>(GetIntermediateMethod);
            return wrapperPredicate;
        }

        private bool GetIntermediateMethod(T arg)
        {
            Func<T, object, bool> linqPredicate = m_QueryExpression.Compile();
            return linqPredicate(arg, m_DesiredParameterValue);
        }
    }
}